package com.jprocms.module.cms.service.sitetpl;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.annotation.JSONField;
import com.jprocms.module.cms.framework.file.FileWrap;

import java.io.File;
import java.nio.charset.Charset;
import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author: zrcms
 */
public class LocalResFile implements IResFile {
    private File file;
    /**
     * 应用的根目录
     */
    private String path;
    private List<IResFile> children;
    //虚拟属性 父id，根节点0,仅用于树展示
    private Integer parentId = 0;
    private Integer id;

    /**
     * 是否包含页面
     */
    private Boolean includePage;

    public LocalResFile(File file, String path, Integer parentId) {
        this.file = file;
        this.path = path;
        this.parentId = parentId;
    }

    public LocalResFile(File file, String path) {
        this.file = file;
        this.path = path;
    }

    @Override
    public List<IResFile> getChildren() {
        return children;
    }

    /**
     * 获得下级目录,不含文件
     * <p>
     * 如果没有指定下级目录，则返回文件夹自身的下级文件，并运用FileFilter。
     *
     * @return
     */
    public List<IResFile> getAllChildren() {
        if (this.children != null) {
            return this.children;
        }
        List<IResFile> list = new ArrayList<>();
        getChildForFile(this, list);
        return list;
    }

    private List<IResFile> getChildForFile(LocalResFile resFile, List<IResFile> container) {
        File[] files = resFile.getFile().listFiles();
        if (files != null) {
            Arrays.sort(files, new FileWrap.FileComparator());
            for (File f : files) {
                if (f.isDirectory()) {
                    LocalResFile fw = new LocalResFile(f, path, resFile.getParentId());
                    //自己的ID设置下级的父层
                    fw.setParentId(resFile.getId());
                    fw.setId(RandomUtil.getSecureRandom().nextInt(Integer.MAX_VALUE));
                    container.add(fw);
                    getChildForFile(fw, container);
                }
            }
        }
        return container;
    }


    @Override
    public String getName() {
        String ap = file.getAbsolutePath().substring(path.length());
        ap = ap.replace(File.separatorChar, '/');
        return ap;
    }

    @Override
    public String getRoot() {
        String name = getName();
        return name.substring(0, name.lastIndexOf('/'));
    }

    @Override
    public String getFilename() {
        return file.getName();
    }

    @Override
    public String getOriginFileName() {
        return getFilename();
    }

    @Override
    public String getSource() {
        if (file.isDirectory()) {
            return null;
        }
        return FileUtil.readString(this.file, Charset.defaultCharset());
    }

    @Override
    public long getLastModified() {
        return file.lastModified();
    }

    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
    @Override
    public LocalDateTime getLastModifiedDate() {
        return LocalDateTimeUtil.of(getLastModified());
    }

    @Override
    public long getLength() {
        return file.length();
    }

    @Override
    public int getSize() {
        return (int) (getLength() / 1024) + 1;
    }

    @Override
    public String getSizeUnit() {
        //定义GB的计算常量
        int gb = 1024 * 1024;
        //定义MB的计算常量
        int mb = 1024;
        //格式化小数
        DecimalFormat df = new DecimalFormat("0.00");
        String resultSize;
        if (getSize() / gb >= 1) {
            //如果当前Byte的值大于等于1GB
            resultSize = df.format(getSize() / (float) gb) + "GB";
        } else if (getSize() / mb >= 1) {
            //如果当前Byte的值大于等于1MB
            resultSize = df.format(getSize() / (float) mb) + "MB";
        } else {
            resultSize = getSize() + "KB";
        }
        return resultSize;
    }

    @Override
    public boolean isDirectory() {
        return file.isDirectory();
    }

    /**
     * 获得被包装的文件
     *
     * @return
     */
    public File getFile() {
        return this.file;
    }

    @Override
    public Boolean getIncludePage() {
        return includePage;
    }

    public void setIncludePage(Boolean includePage) {
        this.includePage = includePage;
    }

    /**
     * 指定下级目录
     *
     * @param children
     */
    public void setChildren(List<IResFile> children) {
        this.children = children;
    }

    public Integer getParentId() {
        return parentId;
    }

    @Override
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public void setParentId(Integer parentId) {
        this.parentId = parentId;
    }
}
